<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of BRepository
 *
 * @author ID59C
 */
class BRepository {

    //private $callerClass = null;
    private $setting = null;
    private static $context = null;

    public function __construct($callerClass, $setting = NULL) {
        //$this->callerClass = $callerClass;
        $this->setting = $setting;
    }

    protected function parseSetting() {
        
    }

    public function findEntity($entity, $context) {

        $context = self::getContext($context, $entity);

        $name = $context->name;
        $statusId = $context->statusId;
        $spaceId = $context->spaceId;
        $appId = $context->appId;
        $class = $context->entityClass;
        $findConditions = $context->findConditions;

        $mClass = $context->modelClass;

        $attributes = array();

        $condition = 'status!=:Status';
        $params = array(':Status' => $statusId);

        $attributes['status_id'] = $statusId;

        if ($name != NULL) {
            $condition.=" and name = :Name";
            $params[':Name'] = $name;
        }

        if ($context->spaceId != NULL) {
            $condition.=" and space_id = :spaceId";
            $params[':spaceId'] = $spaceId;
        }

        if ($appId != NULL) {
            $condition.=" and app_id = :appId";
            $params[':appId'] = $appId;
        }

        if ($findConditions != NULL) {
            foreach ($findConditions as $key => $item) {
                $condition.= " and " . $key . " = :" . $key;
                $params[':' . $key] = $item;
            }
        }

        if ($context->id != NULL && $context->id > 0)
            $mObj = $mClass::model()->findByPk($context->id);
        else {
            $mObj = $mClass::model()->find($condition, $params);
        }

        if ($mObj != NULL) {
            if (isset($mObj->classname))
                $class = $mObj->classname;
            return new $class($mObj->_id);
        }

        return FALSE;
    }

    public function findAllEntity($entity, $context) {

        $context = self::getContext($context, $entity);

        $statusId = $context->statusId;

        $attributes = array();

        $condition = 'status!=:Status';
        $params = array(':Status' => $statusId);

        $attributes['status_id'] = $statusId;

        $name = $context->name;

        if ($name != NULL) {
            $condition.=" and name = :Name";
            $params[':Name'] = $name;
        }

        if ($context->spaceId != NULL) {
            $condition.=" and space_id = :spaceId";
            $params[':spaceId'] = $context->spaceId;
        }

        if ($context->appId != NULL) {
            $condition.=" and app_id = :appId";
            $params[':appId'] = $context->appId;
        }

        $class = $context->entityClass;
        $mClass = $context->modelClass;

        if ($context->findCondition != NULL && $context->findParams != NULL) {
            $condition = $context->findCondition;
            $params = $context->findParams;
        }

        $mObjs = $mClass::model()->findAll($condition, $params);

        $objs = array();

        foreach ($mObjs as $mObj) {
            if ($mObj != NULL)
                $objs[$mObj->_id] = new $class($mObj->_id);
        }

        if ($objs != NULL)
            return $objs;

        return FALSE;
    }

    public function findRelationshipEntity($entity, $context = NULL) {

        $objs = $this->findAllRelationshipEntity($entity, $context);

        if ($objs != NULL)
            return reset($objs);

        return FALSE;
    }

    public function findAllRelationshipEntity($entity, $context = NULL) {

        $context = self::getContext($context, $entity);

        $statusId = $context->statusId;

        $attributes = array();

        $condition = 'status !=:Status';
        $params = array(':Status' => $statusId);

        $attributes['status_id'] = $statusId;

        $name = $context->name;

        if ($name != NULL) {
            $condition.=" and name = :Name";
            $params[':Name'] = $name;
        }

        if ($context->spaceId != NULL) {
            $condition.=" and space_id = :spaceId";
            $params[':spaceId'] = $context->spaceId;
        }

        if ($context->appId != NULL) {
            $condition.=" and app_id = :appId";
            $params[':appId'] = $context->appId;
        }

        if (isset($condition->relationshipId) != NULL) {
            $condition.=" and relationship_id = :relationshipId";
            $params[':relationshipId'] = $context->relationshipId;
        }

        if (isset($entity->mainObj) && $entity->mainObj->getId() != NULL) {
            $col_name = strtolower(substr(get_class($entity->mainObj), 1)) . "_id";
            if ($entity->mainObj instanceof BApp)
                $col_name = 'app_id';
            if (isset($entity->pairObjs) && $entity->pairObjs != null) {
                $col_name = "resource_id";
                $condition.=" and resource_class= '" . get_class($entity->mainObj) . "'";
            }
            $condition.=" and " . $col_name . " = :" . $col_name;
            $params[':' . $col_name] = $entity->mainObj->getId();
        }

        if (isset($entity->pairObj) && $entity->pairObj->getId() != NULL) {
            $col_name = strtolower(substr(get_class($entity->pairObj), 1)) . "_id";
            if ($entity->pairObj instanceof BApp)
                $col_name = 'app_id';
            $condition.=" and " . $col_name . " = :" . $col_name;
            $params[':' . $col_name] = $entity->pairObj->getId();
        }

        if (isset($entity->pairObjs) && $entity->pairObjs != null) {
            foreach ($entity->pairObjs as $pairObj) {
                if ($pairObj->getId() != NULL) {
                    $col_name = strtolower(substr(get_class($pairObj), 1)) . "_id";
                    if ($pairObj instanceof BApp)
                        $col_name = 'app_id';
                    $condition.=" and " . $col_name . " = :" . $col_name;
                    $params[':' . $col_name] = $pairObj->getId();
                }
            }
        }

        $mClass = $context->modelClass;

        $mObjs = $mClass::model()->findAll($condition, $params);
        //$entityClass = get_class($entity);
        $entityList = array();
        $mainObj = $entity->mainObj;
        $pairObjs = $entity->pairObjs;
        if ($entity->pairObj != NULL)
            $pairObjs = $entity->pairObj;
        foreach ($mObjs as $mObj) {
            //$entity = BRelationshipEntity::build($mainObj, $pairObjs);
            $nEntity = clone $entity;
            if ($mObj != NULL) {
                if (property_exists(get_class($nEntity), 'name') && isset($mObj->name))
                    $nEntity->name = $mObj->name;
                if (property_exists(get_class($nEntity), 'description') && isset($mObj->description))
                    $nEntity->description = $mObj->description;
                if (property_exists(get_class($entity), 'data') && isset($mObj->data))
                    $nEntity->data = unserialize($mObj->data);
                if (property_exists(get_class($entity), 'spaceId') && isset($mObj->space_id)) {
                    $nEntity->spaceId = $mObj->space_id;
                }
                if (property_exists(get_class($entity), 'appId') && isset($mObj->app_id)) {
                    $nEntity->appId = $mObj->app_id;
                }
                if (property_exists(get_class($entity), 'status') && isset($mObj->status)) {
                    $nEntity->status = $mObj->status;
                }
                if (property_exists(get_class($entity), 'relationshipId') && isset($mObj->relationship_id)) {
                    $nEntity->relationshipId = $mObj->relationship_id;
                }
                if (property_exists(get_class($entity), 'permitId') && isset($mObj->permit_id)) {
                    $nEntity->permitId = $mObj->permit_id;
                }

                $mainCol = strtolower(substr(get_class($entity->mainObj), 1)) . "_id";
                if ($nEntity->mainObj instanceof BApp)
                    $mainCol = 'app_id';
                if ($nEntity->pairObjs != NULL)
                    $mainCol = 'resource_id';
                $mainClass = get_class($entity->mainObj);
                //if mainObj is loaded obj, no need load it again
                if ($nEntity->mainObj->getId() == NULL)
                    $nEntity->mainObj = new $mainClass($mObj->$mainCol);

                if ($nEntity->pairObj != NULL) {
                    //if pairObj is loaded, do not load it again
                    if ($nEntity->pairObj->getId() == NULL) {
                        $pairClass = get_class($entity->pairObj);
                        $col = strtolower(substr(get_class($entity->pairObj), 1)) . "_id";
                        if ($entity->pairObj instanceof BApp)
                            $col = 'app_id';
                        if ($entity->pairObj instanceof BApp)
                            $nEntity->pairObj = $pairClass::getAppById($mObj->$col);
                        else
                            $nEntity->pairObj = new $pairClass($mObj->$col);
                    }
                }
                //so far, only resource table have more relationship objs, so hardcode col name here
                if ($nEntity->pairObjs != NULL) {
                    foreach ($nEntity->pairObjs as &$pairObj) {
                        if ($pairObj->getId() == NULL) {
                            $pairClass = get_class($pairObj);
                            $col = strtolower(substr(get_class($pairObj), 1)) . "_id";
                            if ($pairObj instanceof BApp)
                                $col = 'app_id';
                            //$mObj->$col = $pairObj->getId();
                            $pairObj = new $pairClass($mObj->$col);
                        }
                    }
                }
            }

            $entityList[$mObj->_id] = $nEntity;
        }


        if ($entityList != NULL)
            return $entityList;

        return array();
    }

    public function saveEntity(&$entity, $context) {

        $context = self::getContext($context, $entity);

        //$context->setEntity($entity);

        $id = $context->id;
        
        if($id == NULL)
            $id = $entity->getId();

        $mClass = $context->getModelClass();

        //save exist item
        if ($id != NULL) {
            $mObj = $mClass::model()->findByPk($id);
        } else {//add new item
            $mObj = new $mClass();
            //$isNewItem = TRUE;
        }

        if ($mObj != NULL) {
            if (property_exists(get_class($entity), 'name')) {
                $mObj->name = $entity->name;
                if ($context->name != NULL)
                    $mObj->name = $context->name;
            }
            if (property_exists(get_class($entity), 'description')) {
                $mObj->description = $entity->description;
                if ($context->description != NULL)
                    $mObj->description = $context->description;
            }
            if (property_exists(get_class($entity), 'data')) {
                $mObj->data = serialize($entity->data);
                if (isset($context->data) && $context->data != NULL)
                    $mObj->data = serialize($context->data);
            }
            if (property_exists(get_class($entity), 'spaceId')) {
                $mObj->space_id = $entity->spaceId;
                if ($context->spaceId != NULL)
                    $mObj->space_id = $context->spaceId;
            }
            if (property_exists(get_class($entity), 'appId')) {
                $mObj->app_id = $entity->appId;
                if ($context->appId != NULL)
                    $mObj->app_id = $context->appId;
            }
            if (property_exists(get_class($entity), 'status')) {
                $mObj->status = $entity->status;
            }
            if (property_exists(get_class($entity), 'relationshipId')) {
                $mObj->relationship_id = $entity->relationshipId;
            }
            if (property_exists(get_class($entity), 'groupTypeId')) {
                $mObj->group_type_id = $entity->groupTypeId;
            }
            if (property_exists(get_class($entity), 'permitId')) {
                $mObj->permit_id = $entity->permitId;
            }
            if (property_exists(get_class($entity), 'groupClass')) {
                $mObj->group_class = $entity->groupClass;
            }

            $saveItems = $context->saveItems;

            foreach ($saveItems as $col => $value) {
                $mObj->$col = $value;
            }

            $mObj->save();
            $entity->id = $mObj->_id;

            return $mObj->_id;
        }
    }

    public function saveRelationshipEntity($entity, $context) {

        if ($entity instanceof BRelationshipEntity)
            $context = self::getContext($context, $entity);

        $mClass = $context->getModelClass();

        if (isset($entity->id)) {
            $mObj = $mClass::model()->findByPk($entity->getId());
        }
        else
            $mObj = new $mClass();

        $mainCol = strtolower(substr(get_class($entity->mainObj), 1)) . "_id";

        if ($entity->pairObj != NULL) {
            $col = strtolower(substr(get_class($entity->pairObj), 1)) . "_id";
            if ($entity->pairObj instanceof BApp)
                $col = "app_id";
            $mObj->$col = $entity->pairObj->getId();
        }
        //so far, only resource table have more relationship objs, so hardcode col name here
        if ($entity->pairObjs != NULL) {
            $mainCol = 'resource_id';
            $mObj->resource_class = $resource_class = get_class($entity->mainObj);
            foreach ($entity->pairObjs as $pairObj) {
                $col = strtolower(substr(get_class($pairObj), 1)) . "_id";
                $mObj->$col = $pairObj->getId();
            }
        }

        $mObj->$mainCol = $entity->mainObj->getId();

        if (property_exists($mClass, 'space_id') && isset($entity->spaceId))
            $mObj->space_id = $entity->spaceId;
        if (property_exists($mClass, 'app_id') && isset($entity->appId))
            $mObj->app_id = $entity->appId;
        if (property_exists($mClass, 'relationship_id') && isset($entity->relationship))
            $mObj->space_id = BRelationship::find($entity->relationship)->getId();
        if (property_exists($mClass, 'status') && isset($entity->status))
            $mObj->status = BStatus::find($entity->status)->getId();
        if (property_exists($mClass, 'data') && isset($entity->data))
            $mObj->data = serialize($entity->data);

        $mObj->save();

        return $mObj->_id;
    }

    public function addChildItem($entity, $context = NULL) {

        $context = self::getContext($context, $entity);


        $mChildClass = $context->modelClass . 'Child';
        $spaceId = $context->spaceId;
        $appId = $context->appId;
        $parentId = $context->parentId;
        $childId = $context->childId;

        $mRow = new $mChildClass();
        $mRow->parent_id = $parentId;
        $mRow->child_id = $childId;
        if ($spaceId != NULL)
            $mRow->space_id = $spaceId;
        if ($appId != NULL)
            $mRow->app_id = $appId;
        return $mRow->save();
        //return TRUE;
    }

    public function removeChildItem($entity, $context = NULL) {

        $context = self::getContext($context);

        $class = get_class($entity);
        $mClass = $context->modelClass;
        $mChildClass = $mClass . 'Child';

        $itemId = null;
        $itemName = null;

        if ($item instanceof $class)
            $itemId = $item->getId();

        if (is_numeric($item))
            $itemId = $item;

        if (is_string($item)) {
            $itemName = $item;
        }

        $children = $entity->getChildren();

        foreach ($children as $item) {
            if ($itemId == NULL && $item->getName() == $itemName) {
                $itemId = $item->getId();
            }
            if ($itemId == $item->getId()) {
                $mItem = $mClass::model()->findByPk($itemId);
                $mItem->status = BStatus::Status_Object_Deleted;
                $mItem->save();

                //also delete from child table
                $mItemChild = $mChildClass::model()->findByAttributes(array('parent_id' => $entity->getId(), 'child_id' => $itemId));
                $mItemChild->status = BStatus::Status_Object_Deleted;
                $mItemChild->save();
            }
        }

        return FALSE;
    }

    public function getChildren($entity, $context = null) {

        $context = self::getContext($context, $entity);
        //$entity = $context->entity;
        $class = get_class($entity);
        $mClass = $context->modelClass;
        //$childClass = $class."Child";
        $mChildClass = $mClass . 'Child';
        $spaceId = $context->spaceId;
        $appId = $context->appId;
        //$name = $context->name;
        $findConditions = $context->findConditions;

        $statusId = $context->statusId;

        $condition = 'parent_id= :parentId and status != :statusId';
        $params = array(':parentId' => $entity->getId(), ':statusId' => $statusId);

        if (isset($entity->spaceId)) {
            $condition .= " and space_id = :spaceId";
            $params[':spaceId'] = $entity->spaceId;
        }

        if (isset($entity->appId)) {
            $condition .= " and app_id = :appId";
            $params[':appId'] = $entity->appId;
        }

        /*
          if ($findConditions != NULL) {
          foreach ($findConditions as $key => $item) {
          $condition.= " and " . $key . " = :" . $key;
          $params[':' . $key] = $item;
          }
          }
         * 
         */

        //$mRows = $mChildClass::model()->findAllByAttributes(array('parent_id' => $this->getId(), 'status' => $statusId));
        $mRows = $mChildClass::model()->findAll(array('condition' => $condition, 'params' => $params));

        $children = array();

        foreach ($mRows as $mRow) {
            $isSelected = TRUE;
            $itemId = $mRow->child_id;
            $child = new $class($itemId);
            if ($spaceId != NULL) {
                if ($child->spaceId != $spaceId) {
                    $isSelected = FALSE;
                }
            }
            if ($appId != NULL) {
                if ($child->appId != $appId)
                    $isSelected = FALSE;
            }

            if ($isSelected)
                $children[$itemId] = $item = new $class($itemId);
        }

        return $children;
    }

    public function getParent($entity, $context = NULL) {

        $context = self::getContext($context, $entity);
        //$entity = $context->entity;
        $class = get_class($entity);
        $mClass = $context->modelClass;
        //$childClass = $class."Child";
        $mChildClass = $mClass . 'Child';
        //$spaceId = $context->spaceId;
        //$appId = $context->appId;

        $statusId = $context->statusId;

        $condition = 'child_id= :childId and status != :statusId';
        $params = array(':childId' => $entity->getId(), ':statusId' => $statusId);

        /*
          if ($spaceId != NULL) {
          $condition .= " and space_id = :spaceId";
          $params[':spaceId'] = $spaceId;
          }

          if ($appId != NULL) {
          $condition .= " and app_id = :appId";
          $params[':appId'] = $appId;
          }
         *
         */

        //$mRows = $mChildClass::model()->findAllByAttributes(array('parent_id' => $this->getId(), 'status' => $statusId));
        $mRows = $mChildClass::model()->findAll(array('condition' => $condition, 'params' => $params));

        $parents = array();

        foreach ($mRows as $mRow) {
            $itemId = $mRow->parent_id;
            $parents[$itemId] = $item = new $class($itemId);
        }

        return $parents;
    }

    public function loadEntity(&$entity, $context = NULL) {

        $context = self::getContext($context, $entity);

        if ($context != NULL) {

            $reload = FALSE;

            if ($context->id != NULL) {
                $entity->id = $context->id;
                $reload = TRUE;
            }
            if ($entity->id != NULL)
                $reload = TRUE;

            if ($reload === TRUE) {
                //$context = new BDataObjContext(get_class($entity), $data);
                $mClass = $context->getModelClass();
                //$entity->id = $context->id;
                $mObj = $mClass::model()->findByPk($entity->id);

                if (property_exists(get_class($entity), 'name') && isset($mObj->name))
                    $entity->name = $mObj->name;
                if (property_exists(get_class($entity), 'description') && isset($mObj->description))
                    $entity->description = $mObj->description;
                if (property_exists(get_class($entity), 'data') && isset($mObj->data))
                    $entity->data = unserialize($mObj->data);
                if (property_exists(get_class($entity), 'spaceId') && isset($mObj->space_id)) {
                    $entity->spaceId = $mObj->space_id;
                }
                if (property_exists(get_class($entity), 'appId') && isset($mObj->app_id)) {
                    $entity->appId = $mObj->app_id;
                }
                if (property_exists(get_class($entity), 'status') && isset($mObj->status)) {
                    $entity->status = $mObj->status;
                }
                if (property_exists(get_class($entity), 'relationshipId') && isset($mObj->relationship_id)) {
                    $entity->relationshipId = $mObj->relationship_id;
                }
                if (property_exists(get_class($entity), 'permitId') && isset($mObj->permit_id)) {
                    $entity->permitId = $mObj->permit_id;
                }

                if (isset($context->loadItems) && is_array($context->loadItems)) {
                    foreach ($context->loadItems as $property => $colName) {
                        if (property_exists(get_class($entity), $property) && isset($mObj->$colName)) {
                            $entity->$property = $mObj->$colName;
                        }
                    }
                }
            }
        }
    }

    public function loadRelationshipEntity(&$entity, $context) {

        $realClass = $entity->getRealEntityClass();

        $mClass = self::getContext()->getModelClass($realClass);

        if (isset($context) && is_numeric($context)) {
            $mObj = $mClass::model()->findByPk($context);
        }

        if ($mObj != NULL) {
            if (property_exists(get_class($entity), 'name') && isset($mObj->name))
                $entity->name = $mObj->name;
            if (property_exists(get_class($entity), 'description') && isset($mObj->description))
                $entity->description = $mObj->description;
            if (property_exists(get_class($entity), 'data') && isset($mObj->data))
                $entity->data = unserialize($mObj->data);
            if (property_exists(get_class($entity), 'spaceId') && isset($mObj->space_id)) {
                $entity->spaceId = $mObj->space_id;
            }
            if (property_exists(get_class($entity), 'appId') && isset($mObj->app_id)) {
                $entity->appId = $mObj->app_id;
            }
            if (property_exists(get_class($entity), 'status') && isset($mObj->status)) {
                $entity->status = $mObj->status;
            }
            if (property_exists(get_class($entity), 'relationshipId') && isset($mObj->relationship_id)) {
                $entity->relationshipId = $mObj->relationship_id;
            }
            if (property_exists(get_class($entity), 'permitId') && isset($mObj->permit_id)) {
                $entity->permitId = $mObj->permit_id;
            }

            $mainCol = strtolower(substr(get_class($entity->mainObj), 1)) . "_id";
            if ($entity->mainObj instanceof BApp)
                $mainCol = 'app_id';
            $mainClass = get_class($entity->mainObj);
            $entity->mainObj = new $mainClass($mObj->$mainCol);

            if ($entity->pairObj != NULL) {
                $pairClass = get_class($entity->pairObj);
                $col = strtolower(substr(get_class($entity->pairObj), 1)) . "_id";
                if ($entity->pairObj instanceof BApp)
                    $col = 'app_id';
                $entity->pairObj = $pairClass::getAppById($mObj->$col);
            }
            //so far, only resource table have more relationship objs, so hardcode col name here
            if ($entity->pairObjs != NULL) {
                $mainCol = 'resource_id';
                $mObj->resource_class = $resource_class = get_class($entity->mainObj);
                $entity->mainObj = new $resource_class($mObj->resource_id);
                foreach ($entity->pairObjs as &$pairObj) {
                    $pairClass = substr(get_class($pairObj), 1);
                    $col = strtolower(substr(get_class($pairObj), 1)) . "_id";
                    if ($pairObj instanceof BApp)
                        $col = 'app_id';
                    $mObj->$col = $pairObj->getId();
                    $pairObj = new $pairClass($mObj->$col);
                }
            }
        }
    }

    public function deletEntity($entityClass, $context) {

        $context = self::getContext($context, $entityClass);

        $mClass = $context->modelClass;

        $id = $context->id;

        //delete just change status
        if ($id != NULL) {
            $mObj = $mClass::model()->findByPk($id);
            $mObj->status = $context->statusId;
            $result = $mObj->save();
            return $result;
        }

        return FALSE;
    }

    public function addGroupMember($group, $member, $context = NULL) {

        $context = self::getContext($context);

        //$mClass = $context->getModelClass(get_class($group)) . 'Member';
        $groupClass = get_class($group);

        if ($member != NULL) {
            $memberClass = get_class($member);
            $tempClass = str_replace("Group", '', $groupClass);
            $memberId = $member->getId();
            $statusId = $context->statusId;
            if ($tempClass == $memberClass) {
                $mClass = $context->getModelClass($groupClass) . 'Member';
                $condition = 'group_class = :GroupClass and member_class = :MemberClass and group_id = :GroupId
					and member_id = :MemberId and status != :StatusId';
                $params = array(':GroupClass' => $groupClass, ':MemberClass' => $memberClass, ':StatusId' => $statusId,
                    ':GroupId' => $group->getId(), ':MemberId' => $memberId);
                if (isset($context->spaceId)) {
                    $condition.='space_id=:spaceId';
                    $params[':spaceId'] = $context->spaceId;
                }
                if (isset($context->appId)) {
                    $condition.='app_id=:appId';
                    $params[':appId'] = $context->appId;
                }
                $mObj = $mClass::model()->find($condition, $params);

                if ($mObj == NULL) {
                    $mGroupMember = new $mClass();
                    $mGroupMember->member_id = $memberId;
                    $mGroupMember->member_class = $memberClass;
                    $mGroupMember->group_id = $group->getId();
                    $mGroupMember->group_class = $groupClass;
                    if (isset($context->spaceId) && is_numeric($context->spaceId)) {
                        $mGroupMember->space_id = $context->spaceId;
                    }
                    if (isset($context->appId) && is_numeric($context->appId)) {
                        $mGroupMember->app_id = $context->appId;
                    }

                    return $mGroupMember->save();
                }
            } else {
                $mClass = $context->getModelClass($groupClass) . substr($memberClass, 1);
                $memberCol = strtolower(substr($memberClass, 1) . "_id");
                $groupCol = strtolower(substr($groupClass, 1) . "_id");

                $condition = $groupCol . ' = :GroupId and ' . $memberCol . ' = :MemberId and status != :StatusId';
                $params = array(':StatusId' => $statusId, ':GroupId' => $group->getId(), ':MemberId' => $memberId);

                if (isset($context->spaceId)) {
                    $condition.='space_id=:spaceId';
                    $params[':spaceId'] = $context->spaceId;
                }
                if (isset($context->appId)) {
                    $condition.='app_id=:appId';
                    $params[':appId'] = $context->appId;
                }
                $mObj = $mClass::model()->find($condition, $params);

                if ($mObj == NULL) {
                    $mGroupMember = new $mClass();
                    $mGroupMember->$memberCol = $memberId;
                    $mGroupMember->$groupCol = $group->getId();
                    if (isset($context->spaceId) && is_numeric($context->spaceId)) {
                        $mGroupMember->space_id = $context->spaceId;
                    }
                    if (isset($context->appId) && is_numeric($context->appId)) {
                        $mGroupMember->app_id = $context->appId;
                    }

                    return $mGroupMember->save();
                }
            }
        }

        return FALSE;
    }

    public function removeGroupMembers($group, $member = null, $context = NULL) {

        $context = BRepository::getContext($context, $group);

        $memberId = NULL;
        $mClass = $context->groupMemberModelClass;
        $groupClass = get_class($group);

        $memberClass = $context->memberClass;

        if (is_string($member))
            $memberClass = $member;
        if ($member instanceof BEntity)
            $memberClass = get_class($member);

        if (is_numeric($member))
            $memberId = $member;

        if ($member instanceof BEntityWithGroup)
            $memberId = $member->getId();

        $statusId_deleted = BStatus::find(BStatus::Status_Object_Deleted)->getId();

        //$statusId = $context->statusId;

        $condition = 'group_class = :GroupClass and member_class = :MemberClass and group_id = :GroupId
					and status != :StatusId';
        $params = array(':GroupClass' => $groupClass, ':MemberClass' => $memberClass, ':Status' => $statusId_deleted,
            ':GroupId' => $group->getId());

        if ($memberClass != NULL) {
            $condition .= ' and member_class = :MemberClass';
            $params[':MemberClass'] = $memberClass;
        }

        if ($memberId != NULL) {
            $condition .= ' and member_id = :MemberId';
            $params[':MemberId'] = $memberId;
        }

        if (isset($context->spaceId)) {
            $condition.='space_id=:spaceId';
            $params[':spaceId'] = $context->spaceId;
        }
        if (isset($context->appId)) {
            $condition.='app_id=:appId';
            $params[':appId'] = $context->appId;
        }

        $mObjs = $mClass::model()->findAll($condition, $params);

        if ($mObjs != NULL) {
            foreach ($mObjs as $mObj) {
                $mObj->status = $statusId_deleted;
                $mObj->save();
            }
            //return removed count
            return count($mObjs);
        }

        return FALSE;
    }

    public function findGroupMember($entity, $context = NULL) {

        $context = BRepository::getContext($context, $entity);

        //$class = get_class($this);
        //$mClass = preg_replace("/^B/", "BM", $class) . "Member";
        $mClass = $context->groupMemberModelClass;
        //$memberClass = preg_replace('/Group/', '', $class);
        $memberClass = $context->memberClass;
        $groupClass = $context->groupClass;

        $statusId = BStatus::Status_Deleted_Id;

        $condition = 'status != :StatusId';
        $params = array(':StatusId' => $statusId);

        if ($entity instanceof BGroup) {
            $groupClass = $groupClass == NULL ? get_class($entity) : $groupClass;
            if (preg_match("/Group/", $groupClass)) {
                $condition.=' and group_id=:groupId';
                $params[':groupId'] = $entity->getId();
                $condition.=' and group_class=:groupClass';
                $params[':groupClass'] = get_class($entity);
            } else {
                $groupCol = strtolower(preg_replace("/^B/", "", get_class($entity))) . "_id";
                $condition.=' and ' . $groupCol . ' =:groupId';
                $params[':groupId'] = $entity->getId();
            }
        }

        if ($context->spaceId && $context->spaceId > 0) {
            $condition.=' and space_id=:spaceId';
            $params[':spaceId'] = $context->spaceId;
        }
        if ($context->appId && $context->appId > 0) {
            $condition.=' and app_id=:appId';
            $params[':appId'] = $context->appId;
        }

        $mObjs = $mClass::model()->findAll($condition, $params);

        if ($entity instanceof BGroup) {
            $members = array();
            foreach ($mObjs as $mObj) {
                if (preg_match("/Group/", $groupClass)) {
                    $members[$mObj->member_id] = new $memberClass($mObj->member_id);
                } else {
                    $memberCol = strtolower(preg_replace("/^B/", "", $memberClass)) . "_id";
                    $members[$mObj->$memberCol] = new $memberClass($mObj->$memberCol);
                }
            }

            if ($members != NULL)
                return $members;
        }

        return FALSE;
    }

    public function findMemberGroups($entity, $context = NULL) {
        $context = BRepository::getContext($context, $entity);

        //$class = get_class($this);
        //$mClass = preg_replace("/^B/", "BM", $class) . "Member";
        $mClass = $context->groupMemberModelClass;
        //$memberClass = preg_replace('/Group/', '', $class);
        //$memberClass = $context->memberClass;
        $groupClass = $context->groupClass;

        $statusId = BStatus::find(BStatus::Status_Object_Deleted)->getId();

        $condition = 'status != :StatusId';
        $params = array(':StatusId' => $statusId);

        if ($entity instanceof BEntityWithGroup) {
            if (preg_match("/Group/", $groupClass)) {
                $condition.=' and member_id=:memberId';
                $params[':memberId'] = $entity->getId();
                $condition.=' and member_class=:memberClass';
                $params[':memberClass'] = get_class($entity);
            } else {
                $memberCol = strtolower(preg_replace("/^B/", "", get_class($entity))) . "_id";
                $condition.=' and ' . $memberCol . ' =:memberId';
                $params[':memberId'] = $entity->getId();
            }
        }

        if ($context->spaceId && $context->spaceId > 0) {
            $condition.=' and space_id=:spaceId';
            $params[':spaceId'] = $context->spaceId;
        }
        if ($context->appId && $context->appId > 0) {
            $condition.=' and app_id=:appId';
            $params[':appId'] = $context->appId;
        }

        $mObjs = $mClass::model()->findAll($condition, $params);

        if ($entity instanceof BEntityWithGroup) {
            $groups = array();
            foreach ($mObjs as $mObj) {
                if (preg_match("/Group/", $groupClass)) {
                    $groups[$mObj->group_id] = new $groupClass($mObj->group_id);
                } else {
                    $groupCol = strtolower(preg_replace("/^B/", "", $groupClass)) . "_id";
                    $groups[$mObj->$groupCol] = new $groupClass($mObj->$groupCol);
                }
            }

            if ($groups != NULL)
                return $groups;
        }

        return FALSE;
    }

    /**
     * @return BRepositoryContext
     * @param type $data
     */
    public static function getContext($data = NULL, $entity = null) {

        if (!$data instanceof BRepositoryContext) {
            self::$context = new BRepositoryContext($entity, $data);
        } else {
            self::$context = $data;
        }

        if ($data instanceof BRepositoryContext) {
            self::$context->entity = $entity instanceof BEntity ? $entity : self::$context->entity;
            $entityClass = $entity instanceof BEntity ? get_class($entity) : $entity;
            if ($entityClass != self::$context->entityClass) {
                self::$context->entityClass = $entityClass;
                self::$context->parseData();
            }
        }


        return self::$context;
    }

    public function getCount($entity, $context = NULL) {
        $context = self::getContext($context, $entity);
        $mClass = $context->getModelClass();

        $count = $mClass::model()->count();

        return $count;
    }

}
?>
